package com.suning.sawp.web.filter;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.suning.sawp.service.util.SCMConfigUtil;
/**
 * 
 * 校验客户端版本号<br> 
 * 〈功能详细描述〉
 *
 * @author 12061818
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class ClientVersionFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientVersionFilter.class);
    
    /**
     * 校验客户端版本号开关
     */
    private static final String VALID_CLIENT_VERSION = "validClientVersion";
    
    /**
     * IOS版本号规则校验
     */
    private static final Pattern IOS_VERSION_PATTERN = Pattern.compile("\\d.\\d.\\d");
    
    /**
     * IOS客户端版本号
     */
    private static final String IOS_VERSION = "iosVersion";
    
    /**
     * Android客户端版本号
     */
    private static final String ANDROID_VERSION = "androidVersion";
    
    /**
     * 版本校验不通过，返回提示文案
     */
    private static final String VERSION_ERROR_MSG = "{\"retFlag\":\"0\",\"errorCode\":\"0026\",\"errorMessage\":\"您的客户端版本过低，要下载最新版才能使用哦~\",\"data\":\"http://mapp.suning.com/a.php?s=qrcode/offline&f=suningplus&pack=com.suning.mobile.im.clerk&ActionTag=1&uuid=qr3C64E48AEBCF83583A4461FB1759B0B8\"}";
    public static void main(String[] args) {
        System.out.println(VERSION_ERROR_MSG);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        boolean validResult = true;
        String userAgent = httpRequest.getHeader("User-Agent");
        try {
            // 客户端版本号校验开关是否打开
            String validFlag = SCMConfigUtil.getConfig(VALID_CLIENT_VERSION);
            if (StringUtils.isNotBlank(validFlag) && Boolean.valueOf(validFlag)){
                if (StringUtils.isNotBlank(userAgent)) {
                    userAgent = userAgent.toLowerCase();
                    String version = getClientVersion(userAgent);
                    if (StringUtils.isBlank(version)) {
                        validResult = false;
                    } else {
                     // 判断请求来自IOS还是Android
                        if (userAgent.contains("iphone")) {
                            // ios 版本号 1.2.3
                            String iosVersion = SCMConfigUtil.getConfig(IOS_VERSION);
                            String[] clientNums = version.split("\\.");
                            String[] scmNums = iosVersion.split("\\.");
                            for (int i = 0; i < scmNums.length; i++) {
                                if (Integer.parseInt(scmNums[i]) > Integer.parseInt(clientNums[i])) {
                                    validResult = false;
                                    break;
                                } else if (Integer.parseInt(scmNums[i]) < Integer.parseInt(clientNums[i])) {
                                    break;
                                }
                            }
                        } else if (userAgent.contains("android")) {
                            // Android 版本号 数字
                            String androidVersion = SCMConfigUtil.getConfig(ANDROID_VERSION);
                            if (Integer.parseInt(version) < Integer.parseInt(androidVersion)) {
                                // 小于SCM配置的版本号，版本过低，需要强制升级
                                validResult = false;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("ClientVersionFilter valid client version error. user-agent:{}", userAgent, e);
            validResult = false;
        }
        
        
        if (validResult) {
            // 校验通过，流转至下一步filter
            chain.doFilter(httpRequest, httpResponse);
            return;
        } else {
            // 版本号校验不通过
            httpResponse.setContentType("application/json;charset=utf-8");
            httpResponse.addHeader("Cache-Control", "no-cache");
            httpResponse.addHeader("versionFlag", "false");
            httpResponse.getOutputStream().write(VERSION_ERROR_MSG.getBytes("UTF-8"));
            httpResponse.getOutputStream().flush();
            httpResponse.getOutputStream().close();
        }
    }

    /**
     * 
     * 功能描述: 取客户端版本号<br>
     * 〈功能详细描述〉
     *
     * @param userAgent
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getClientVersion(String userAgent) {
        String[] args = userAgent.split(";");
        String versionStr = args[args.length - 1];
        String version = null;
        if (versionStr.contains("version")) {
            String[] tmps = versionStr.split(":");
            if (tmps.length == 2) {
                version = tmps[1];
                if (userAgent.contains("iphone")) {
                    // IOS 版本号1.2.3 校验客户端IOS版本号
                    Matcher matcher = IOS_VERSION_PATTERN.matcher(version);
                    if (!matcher.matches()) {
                       version = null; 
                    }
                } else if (userAgent.contains("android")) {
                    // Android 版本号 数字 校验客户端Android版本号
                    if (!NumberUtils.isDigits(version)) {
                        version = null;
                    }
                }
            }
        }
        
        return version;
    }
    
    @Override
    public void destroy() {
        
    }

}
